package d.n.d.dao;

import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import d.n.d.domain.Account;
import d.n.d.domain.Transaction;

/**
 * 
 * @author D.N.D
 *
 */
@Repository
public class TransactionDaoImpl implements TransactionDao {

	@PersistenceContext
	private EntityManager em;

	/**
	 * @return List<Transaction>
	 */
	public List<Transaction> getTransactionListByAccountId(String accountId) {

		TypedQuery<Transaction> query = em
				.createQuery(
						"SELECT t FROM Transaction t WHERE t.sendAccount.accountNumber= :accountId",
						Transaction.class);

		return query.setParameter("accountId", accountId).getResultList();
	}

	/**
	 * @return List<Transaction>
	 */
	public List<Transaction> getTransactionListByCustomer(Date from, Date to,
			String userId) {

		TypedQuery<Transaction> query = em
				.createQuery(
						"SELECT t FROM Transaction t WHERE t.beginTime >= :from and t.endTime <= :to and t.sendAccount.accountNumber= :userId",
						Transaction.class);
		return query.setParameter("from", from).setParameter("to", to)
				.setParameter("userId", userId).getResultList();
	}

	/**
	 * <br> Author: DucDS </br>
	 * @return List<Transaction>
	 */
	public List<Transaction> getTransactionListPending() {

		TypedQuery<Transaction> query = em
				.createQuery(
						"SELECT t FROM  Transaction t WHERE t.transactionStatus = :statusPending ORDER BY t.idTransaction ",
						Transaction.class).setParameter("statusPending",
						"Pending");
		return query.getResultList();
	}

	/**
	 * @return Transaction
	 */
	public Transaction findTransactionById(int transactionId) {
		
		return em.find(Transaction.class, transactionId);
	}
	
	/**
	 * @return boolean
	 */
	@Transactional
	public boolean insertNewTransaction(Transaction newTransaction) {
		em.persist(newTransaction);
		return true;
	}
	
	/**
	 * @return Transaction
	 */
	public Transaction findTransactionByStringId(String transactionId) {
		
		try {
			Integer.parseInt(transactionId);
		} catch (NumberFormatException e) {
			return null;
		}
		return em.find(Transaction.class, Integer.parseInt(transactionId));

	}

	/**
	 * @return boolean
	 */
	@Transactional
	public boolean updateTransaction(Transaction transaction) {

		em.merge(transaction);
		return true;
	}
	
	/**
	 * @return boolean
	 */
	@Transactional
	public boolean update(Account account, Transaction transaction) {
		em.merge(transaction);
		em.merge(account);
		return true;
	}
	
	/**
	 * @return boolean
	 */
	@Transactional
	public boolean update(Account sendAccount,Account receiveAccount, Transaction transaction){
		em.merge(transaction);
		em.merge(sendAccount);
		em.merge(receiveAccount);
		return true;
	}
}
